(function () {
  // Note: 后续都转到 ui.js
  var UIComponent = window.UIComponent = {
    init: function (container, context) {
      var $container = $(container);
      var $elements = null;

      if ($container.data('ui')) {
        $elements = $container;
      } else {
        $elements = $container.find('[data-ui]');
      }

      var groups = {};

      $elements.each(function () {
        var $element = $(this);
        var componentName = $element.data('ui');

        // if in auto bind process (document ready), by pass the component if auto bind is set to false
        if (context && context.is_in_auto_bind_process && $element.data('ui-auto-bind') === false) {
          return;
        }

        if (!groups[componentName]) {
          groups[componentName] = [];
        }

        groups[componentName].push($element);
      });

      _.each(_.keys(groups), function (name) {
        var handler = UIComponent.handlers[name];
        if (handler) {
          handler.init(groups[name]);
        }
      });
    }
  };

  UIComponent.handlers = {};

  UIComponent.handlers['inline-user-info'] = {
    init: function ($elements) {
      var ids = _.map($elements, function ($element) {
        return $element.data('uid');
      });

      ids = _.filter(_.uniq(ids), function (id) {
        return !!id;
      });

      if (ids.length === 0) {
        return;
      }

      $.get('/backend/users/api_get_user_infos', {ids: ids.join(',')}, function (result) {
        _.each($elements, function ($element) {
          var uid = $element.data('uid');
          var user = result[uid];
          if (!user) {
            return;
          }

          var html  = '<span>' + user.nickname;

          if (user.type === 'vip_channel') {
            html += ' <i class="fa fa-diamond js-tooltip" style="color:goldenrod" title="VIP渠道"></i>'
          }

          html += '</span>';

          $element.html(html);
          $element.find('i').tooltip();
          if ($element[0].tagName === 'A') {
            UIComponent.handlers['user-info-popover'].init([$element]);
            if ($element.data('link-url')) {
              var url = Handlebars.compile($element.data('link-url'))(user);
              $element.attr('href', url);
            }
          }
          // 订单列表的全部 收款信息
          if ($element.data('formatter') === 'payment') {
            $element.html('<span>' + user.card_holder_name + " " + user.card_number + '</span>');
          }
        });
      });
    }
  };

  UIComponent.handlers['inline-user-realname'] = {
    init: function ($elements) {
      var ids = _.map($elements, function ($element) {
        return $element.data('uid');
      });

      ids = _.filter(_.uniq(ids), function (id) {
        return !!id;
      });

      if (ids.length === 0) {
        return;
      }

      $.get('/backend/users/api_get_user_realnames', {ids: ids.join(',')}, function (result) {
        _.each($elements, function ($element) {
          var uid = $element.data('uid');
          var user = result[uid];
          if (!user) {
            return;
          }

          var fullRealName = 'N/A';
          var realName = fullRealName;
          if (user.card_holder_name) {
              realName = fullRealName = user.card_holder_name;

              var maxLength = $element.data('max-length');
              if (maxLength && fullRealName.length > 5) {
                  realName = fullRealName.substr(0, 5) + '...';
              }
          }

          var html = '<span style="display: inline-block;" title="' + fullRealName + '">收款: ' + realName + '</span>';

          if (user.vip_channel) {
            html += '<span title="VIP" style="display:inline-block;margin-left:5px;"><i class="fa fa-diamond" style="color:goldenrod"></i> ' + user.vip_channel.nickname + '</span>';
          }

          $element.html(html);
        });
      });
    }
  };

  UIComponent.handlers['user-search-box'] = {
    init: function ($elements) {
      _.each($elements, function ($element) {
        var placeholder = $element.data('placeholder');
        $element.width(300);

        var params = {
          user_type: $element.data('user-type')
        };

        if (!params.user_type) {
          throw new Error('UserSearchBox: user_type attribute is required');
        }

        if ($element.data('upline-uid')) {
          params.upline_uid = $element.data('upline-uid');
        }

        if ($element.data('business-specialist-uid')) {
          params.business_specialist_uid = $element.data('business-specialist-uid');
        }

        if ($element.data('created-by-id')) {
          params.created_by_id = $element.data('created-by-id');
        }

        if ($element.data('self-owned') !== undefined) {
          params.self_owned = $element.data('self-owned');
        }

        if ($element.data('user-role')) {
          params.user_role = $element.data('user-role');
        }

        var formatItem = function (item) {
          if (!item.id) {
            return item.text;
          }

          var text = item.text;
          if (item.type === 'vip_channel' || item.type === 'agent') {
            text += '&nbsp;<span class="text-success" style="font-size:12px">' + iread.langs['user_type_' + item.type] + '</span>';
          }

          return $('<span>' + text + '</span>');
        };

        iread.ui.zselect.init($element, {
          placeholder: placeholder,
          value: $element.data('value'),
          ajax: {
            url: '/backend/users/api_search?' + $.param(params),
            mapItem: function (it) {
              return {
                id: it.id,
                type: it.type,
                text: it.nickname + ' (' + it.username + ')'
              };
            }
          },
          templateResult: formatItem,
          templateSelection: formatItem
        });
      });
    }
  };

  UIComponent.handlers['vip-child-channel-search-box'] = {
    init: function ($elements) {
      _.each($elements, function ($element) {
        var placeholder = $element.data('placeholder');
        $element.width(300);
        var selectd_id = null;

        $element.select2({
          placeholder: placeholder,
          ajax: {
            url: '/backend/vip_channel/api_search_child_users',
            dataType: 'json',
            quietMillis: 100,
            delay: 250,
            data: function (params) {
              return {
                q: params.term,
                page: params.page
              };
            },
            processResults: function (data) {
              return {
                results: data
              };
            }
          },
          templateResult: function formatRepoSelection(repo) {
            if (!repo.id) return '';
            return repo.nickname + ' (' + repo.username + ')';
          },
          templateSelection: function formatRepoSelection(repo) {
             if (!repo.id) return placeholder;
             if (repo.nickname && repo.username) {
               return repo.nickname + ' (' + repo.username + ')';
             } else {
               return repo.text;
             }
          },
          selectOnClose: true
        });

        if ($element.data('selectd-id')) {
          selectd_id = $element.data('selectd-id');
          $.get('/backend/vip_channel/api_get_child_channel_by_id?id='+selectd_id, function (data) {
            $element.append("<option value='"+selectd_id+"' >"+data.nickname + ' (' + data.username + ')'+"</option>");
          });
        }

      });
    }
  };

  UIComponent.handlers['bs-group-search-box'] = {
    init: function ($elements) {
      _.each($elements, function ($element) {
        var placeholder = $element.data('placeholder');
        $element.width(200);

        var params = {
          uid: $element.data('uid')
        };

        $element.select2({
          placeholder: placeholder,
          ajax: {
            url: '/backend/business_specialist/api_get_bs_group_list/' + params.uid,
            dataType: 'json',
            quietMillis: 100,
            delay: 250,
            data: function (params) {
              return {
                q: params.term,
                page: params.page
              };
            },
            processResults: function (data) {
              return {
                results: data
              };
            }
          },
          templateResult: function formatRepoSelection(repo) {
            if (!repo.id) return '';
            return repo.name;
          },
          templateSelection: function formatRepoSelection(repo) {
            if (!repo.id) return placeholder;
            return repo.name;
          }
        });
      });
    }
  };

  UIComponent.handlers['user-info-popover'] = {
    init: function ($elements) {
      var buildHtmlRow = function (label, content) {
        return '<div class="form-group" style="margin-bottom:0">' +
          '<label class="control-label col-sm-4">' + label + '</label>' +
          '<div class="col-sm-8 no-padding-left"><div class="form-control-static">' + content + '</div></div>' +
          '</div>';
      };

      _.each($elements, function ($element) {
        var uid = $element.data('uid');
        if (!uid) {
          return;
        }

        $element.css('cursor', 'pointer');
        $element.webuiPopover({
          title: null,
          trigger: 'hover',
          delay: {
            show: 300
          },
          width: 350,
          type: 'async',
          url: '/backend/users/api_get_user_popover_info/' + uid,
          content: function (data) {
            var html =
              '<div class="form-horizontal">' +
              buildHtmlRow('用户名', data.username) +
              buildHtmlRow('昵称', data.nickname);

            var mp = null;

            if (data.type === 'agent') {
              html += buildHtmlRow('所属渠道', data.channel.nickname);
              mp = data.channel.mp;
            } else {
              mp = data.mp;
            }

            if (data.type === 'channel' || data.type === 'agent') {
              if (mp) {
                html += buildHtmlRow('渠道公众号',
                  '<img style="width:100px;border:#eee 1px solid;" src="//open.weixin.qq.com/qr/code?username=' + mp.raw_id + '"/>' +
                  '<div style="margin-top:5px">' + mp.nickname + '</div>');
                if (data.follow_mode) {
                  html += buildHtmlRow('关注模式', iread.langs['follow_mode_' + data.follow_mode]);
                }
              } else {
                html += buildHtmlRow('渠道公众号', '未配置');
              }
            }

            if (data.site_url) {
              html += buildHtmlRow('首页地址', data.site_url);
            }

            if (data.type === 'channel') {
              if (data.bs_info) {
                html += buildHtmlRow('商务归属', data.bs_info.bs_name);
                html += buildHtmlRow('商务分组', data.bs_info.bs_group_name);
              }

              if (data.payee_account && data.payee_account.holder_name) {
                html += buildHtmlRow('收款人', data.payee_account.holder_name);
              }

              if (data.test_group_names) {
                html += buildHtmlRow('测试分组', data.test_group_names);
              }
            }

            html += '</div>';

            return html;
          }
        });
      });
    }
  };

  UIComponent.handlers['inline-member-info'] = {
    init: function ($elements) {
      var ids = _.map($elements, function ($element) {
        return $element.data('member-id');
      });

      ids = _.filter(_.uniq(ids), function (id) {
        return !!id;
      });

      if (ids.length === 0) {
        return;
      }

      // 串行请求
      var ids_group = _.chunk(ids, 100);
      var key = 0;

      function batch_get(key) {
        $.get('/backend/members/api_get_member_infos', {ids: ids_group[key].join(',')}, function (result) {
          _.each($elements, function ($element) {
            var memberId = $element.data('member-id');
            var member = result[memberId];
            if (member) {
              var html = '';
              if (member.headimgurl) {
                html += '<img style="width:18px;margin-right:5px" src="' + member.headimgurl + '"/>'
              }

              var text = member.nickname
                ? '<span>' + member.nickname + '</span>' + ' <span>(' + memberId + ')</span>'
                : '<span>' + memberId + '</span>';

              if ($element.data('link-to-detail')) {
                html += '<a href="/backend/members/view/' + memberId + '">' + text + '</a>';
              } else {
                html += text;
              }

              var buildRow = function (field, value) {
                return '<div class="form-group" style="margin-bottom:0">' +
                  '<label class="control-label col-sm-4">' + field + '</label>' +
                  '<div class="col-sm-8 no-padding-left"><p class="form-control-static">' + value + '</p></div>' +
                  '</div>'
              };

              $element.html(html);
              if (!(/Mobi|Android/i.test(navigator.userAgent))) {
                $element.webuiPopover({
                  title: null,
                  trigger: 'hover',
                  delay: {
                    show: 300
                  },
                  width: 350,
                  content: '<div class="form-horizontal">'
                      + buildRow('ID', member.id)
                      + buildRow('昵称', member.nickname || '')
                      + buildRow('创建时间', member.create_time)
                      + buildRow('关注时间', member.subscribe_time || '-')
                      + buildRow('当前关注状态', member.subscribe ? '关注' : '未关注')
                      + '</div>'
                });
              }
            }
          });
        }).then(function () {
          if (key < ids_group.length - 1) {
            key++;
            batch_get(key)
          }
        })
      }

      batch_get(key);
    }
  };

  UIComponent.handlers['novel-search-box'] = {
    init: function ($elements) {
      _.each($elements, function ($element) {
        iread.ui.zselect.init($element, {
          value: $element.data('nid') || null,
          ajax: {
            url: '/backend/novels/api_search',
            data: function () {
              return {online_only: typeof($element.data('online-only')) !== "undefined" ? $element.data('online-only') : 1}
            },
            mapItem: function (item) {
              return { id: item.id, text: item.title }
            }
          }
        })
      })
    }
  };

  UIComponent.handlers['novel-tag-search-box'] = {
    init: function ($elements) {
      _.each($elements, function ($element) {
        var placeholder = $element.data('placeholder');
        $element.width(200);

        $element.select2({
          placeholder: placeholder,
          ajax: {
            url: '/backend/novel_tag/api_get_novel_tags',
            dataType: 'json',
            quietMillis: 100,
            delay: 250,
            data: function (params) {
              return {
                keyword: params.term,
                page: params.page
              };
            },
            processResults: function (data, params) {
              params.page = params.page || 1;
              return {
                results: data,
                pagination: {
                  more: data.length == 20
                }
              };
            }
          },
          templateResult: function formatRepoSelection(repo) {
            if (!repo.id) return '';
            return repo.name;
          },
          templateSelection: function formatRepoSelection(repo) {
            if (!repo.id) return placeholder;
            return repo.name;
          }
        });
      });
    }
  };

  UIComponent.handlers['payee-account-stats-popover'] = {
    init: function ($elements) {
      _.each($elements, function ($element) {
        var holderName = $element.data('holder-name');
        var accountNo = $element.data('account-no');
        var sourceType = $element.data('source-type');

        $element.webuiPopover({
          title: null,
          trigger: 'hover',
          delay: {
            show: 300
          },
          width: 350,
          type: 'async',
          url: '/backend/financial/ent_payments/api_get_payee_account_stats?source_type='
            + sourceType + '&account_no=' + accountNo + '&holder_name=' + holderName,
          content: function (data) {
            if (data.length === 0) {
              return '<div class="text-center" style="padding:30px">今日没有打款记录</div>';
            }

            var html = '<table class="table">';
            html += '<thead><tr><th>商户号</th><th class="text-right">今日打款</th></tr></thead>';

            _.each(data, function (it) {
              html += '<tr><td>' + it.payment_account.name + '</td><td class="text-right">&yen; ' + numeral(it.amount / 100).format('0,0.00') + '</td></tr>'
            });

            html += '</table>';

            return html;
          }
        });
      });
    }
  };

  UIComponent.handlers['payment-account-stats-popover'] = {
    init: function ($elements) {
      _.each($elements, function ($element) {
        var id = $element.data('account-id');
        var sourceType = $element.data('source-type') || '';

        $element.webuiPopover({
          title: null,
          trigger: 'hover',
          delay: {
            show: 300
          },
          width: 540,
          type: 'async',
          url: '/backend/financial/ent_payments/api_get_payment_account_stats/' + id + '?source_type=' + sourceType,
          content: function (data) {
            if (data.length === 0) {
              return '<div class="text-center" style="padding:30px">今日没有打款记录</div>';
            }

            var html = '<table class="table">';
            html += '<thead><tr><th>付款方式</th><th class="text-right">今日打款</th><th class="text-right">今日实际支出</th></tr></thead>';

            _.each(data, function (it) {
              html += '<tr><td>' + it.payment_method_name + '</td>' +
                '<td class="text-right">&yen; ' + numeral(it.amount / 100).format('0,0.00') + ' (手续费: &yen; ' + numeral(it.commission_fee / 100).format('0,0.00') + ')' + '</td>' +
                '<td class="text-right">&yen; ' + numeral((it.amount + it.commission_fee) / 100).format('0,0.00') + '</td>' +
                '</tr>'
            });

            html += '</table>';

            return html;
          }
        });
      });
    }
  };

  UIComponent.handlers['table-sort'] = {
    init: function ($elements) {
      var qs = parseQueryString();

      _.each($elements, function ($element) {
        $element.css('cursor', 'pointer');
        $element.attr('title', '点击排序');
        $element.append('<i class="fa table-sort-icon" style="display:none"></i>');

        var $icon = $element.find('.table-sort-icon');

        var field = $element.data('field');
        var startDir = $element.data('start-dir') || 'asc';
        var orderBy = qs.order_by ? parseOrderBy(qs.order_by) : null;

        // update icon status from query string
        if (orderBy && orderBy.field === field) {
          if (orderBy.dir === 'asc') {
            $icon.removeClass('fa-caret-down').addClass('fa-caret-up');
          } else {
            $icon.removeClass('fa-caret-up').addClass('fa-caret-down');
          }

          $icon.show();
        }

        $element.click(function () {
          var dir = startDir;
          if (orderBy && orderBy.field === field) {
            dir = orderBy.dir === 'asc' ? 'desc' : 'asc';
          }

          var newQs = _.assign({}, qs);

          delete newQs.page;

          newQs.order_by = field + ' ' + dir;

          var search = _.chain(newQs)
            .map(function (value, key) {
              return key + '=' + encodeURIComponent(value);
            })
            .value()
            .join('&');

          location.href = location.pathname + '?' + search;
        });
      });

      function parseOrderBy(value) {
        if (!value) {
          return null;
        }

        var parts = value.split(' ');
        if (parts.length === 1) {
          return {field: parts[0], dir: 'asc'};
        }

        return {field: parts[0], dir: parts[1]};
      }
    }
  };

  UIComponent.handlers['ref-link-search-box'] = {
    init: function ($elements) {
      _.each($elements, function ($element) {
        var url = '/admin/customservice/api_suggest?q=%QUERY&type=' + (window.referral_link_type || '');

        var channelId = $element.data('channel-id');
        if (channelId) {
          url += '&chid=' + channelId;
        }

        $element.typeahead({
          minLength: 0
        }, {
          name: 'ref_link_source',
          display: 'url',
          // 呵呵，我得服 typeahead 的这个 bug，limit 10 的时候，服务端返回 10条记录也不会显示
          // https://github.com/twitter/typeahead.js/issues/1201
          limit: 20,
          source: new Bloodhound({
            datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
            queryTokenizer: Bloodhound.tokenizers.whitespace,
            remote: {
              url: url,
              wildcard: '%QUERY'
            }
          }),
          templates: {
            suggestion: Handlebars.compile(
              '<div><span>{{description}}</span><div class="text-muted" style="font-size:13px;">{{url}}</div></div>'
            )
          }
        });

        // 这里改用select事件, 选中后自动触发change和blur事件, 方便modal中订阅事件生成短链执行
        $element.on('typeahead:select', function (ev, suggestion) {
          if (suggestion.id) {
            $(this).attr('data-selected-id', suggestion.id);
          }

          $(this).trigger('change');
          $(this).trigger('blur');
        });
      });
    }
  };

  UIComponent.handlers['group-check'] = {
    init: function ($elements) {
      _.each($elements, function ($element) {
        $element.click(function () {
          var $items = $($(this).data('item-selector') || '.check-item');
          $items.prop('checked', $(this).is(':checked'));
        })
      })
    }
  };

  UIComponent.handlers['app-click-action'] = {
    init: function ($elements) {
      var parsed = _.transform($elements, function (result, $element) {
        var id = $element.data('id');
        if (id) {
          result.actions[id] = decodeURIComponent($element.data('value'));
          result.map[id] = $element;
        }
      }, {
        actions: {},
        map: {}
      });

      $.ajax({
        url: '/backend/app_click_action/humanize',
        method: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(parsed.actions)
      })
        .then(function (result) {
          for (var id in result) {
            var html = '<span style="white-space: pre-wrap;">';
            html += result[id];
            html += '</span>';

            parsed.map[id].html(html);
          }
        });
    }
  };
})();
